// File: src/ui/cli/CliHandler.cpp
#include "CliHandler.h"
#include <iostream>
#include <iomanip>
#include <ctime>
#include <algorithm>
#include <cctype>
#include <sstream>
#include <termios.h>
#include <unistd.h>

#include "core/tasks/Task.h"

CliHandler::CliHandler() {
    authManager.loadFromFile();
}

void CliHandler::handleCommand(int argc, char* argv[]) {
    if (argc < 2) {
        showHelp();
        return;
    }

    std::string command = argv[1];
    std::string username;
    // 帮助代码
    if (command == "help" || command == "--help" || command == "-h") 
    {
        showHelp();
    }
    // 查看版本
    else if (command == "version" || command == "--version" || command == "-v") 
    {
        showVersion();
    }
    // 用户注册
    else if (command == "register") 
    {
        if (argc < 4) {
            std::cerr << "用法: " << argv[0] << " register <用户名> <密码>" << std::endl;
            return;
        }
        registerUser(argv[2], argv[3]);
    }
    // 进入交互模式
    else if (command == "run") {
        if (argc < 4) {
            std::cerr << "用法: " << argv[0] << " run <用户名> <密码>" << std::endl;
            return;
        }
        if (authManager.authenticate(argv[2], argv[3])) {
            username = argv[2];
            xpSystem.loadFromFile(username, territories);
            runInteractive(username);
        }
    }
    // 添加任务
    else if (command == "addtask") {
        if (argc < 4) {
            std::cerr << "用法: " << argv[0] << " addtask <用户名> <密码> [任务参数...]" << std::endl;
            return;
        }
        if (authManager.authenticate(argv[2], argv[3])) {
            username = argv[2];
            xpSystem.loadFromFile(username, territories);
            std::vector<std::string> args(argv + 4, argv + argc);
            addTask(args);
        }
    }
    // 显示任务
    else if (command == "showtasks") {
        if (argc < 5) {
            std::cerr << "用法: " << argv[0] << " showtasks <用户名> <密码> <范围> [日期]" << std::endl;
            return;
        }
        if (authManager.authenticate(argv[2], argv[3])) {
            username = argv[2];
            taskManager.loadTasks(username); //从taskManager加载用户任务数据
            std::vector<std::string> args(argv + 4, argv + argc);
            showTasks(args);
        }
    }
    // 删除任务
    else if (command == "deltask") {
        if (argc < 5) {
            std::cerr << "用法: " << argv[0] << " deltask <用户名> <密码> <任务ID>" << std::endl;
            return;
        }
        if (authManager.authenticate(argv[2], argv[3])) {
            username = argv[2];
            xpSystem.loadFromFile(username, territories);
            std::vector<std::string> args(argv + 4, argv + argc);
            deleteTask(args);
        }
    }
    // 游戏王国功能
    else if (command == "kingdom") {
        if (argc < 4) {
            std::cerr << "用法: " << argv[0] << " kingdom <用户名> <密码>" << std::endl;
            return;
        }
        if (authManager.authenticate(argv[2], argv[3])) {
            username = argv[2];
            xpSystem.loadFromFile(username, territories);
            showKingdom(username);
        }
    }
    else {
        std::cerr << "未知命令: " << command << std::endl;
        showHelp();
    }
    if(!username.empty())
        xpSystem.saveToFile(username, territories);
}

std::string CliHandler::getPasswordFromConsole() {
    struct termios oldt, newt;
    std::string password;
    
    // 获取当前终端设置
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    
    // 禁用回显（ECHO）
    newt.c_lflag &= ~ECHO;
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    
    // 读取密码
    std::getline(std::cin, password);
    
    // 恢复终端设置
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    
    return password;
}

void CliHandler::runInteractive(const std::string& currentUser) {
    // 如果未提供用户名，要求先登录
    std::string username;
    if (currentUser.empty()) {
        std::cout << "请先登录或注册：" << std::endl;
        std::string input, password;
        
        while (true) {
            std::cout << "1. 登录\n2. 注册\n选择操作: ";
            std::getline(std::cin, input);
            
            if (input == "1") {
                std::cout << "用户名: ";
                std::getline(std::cin, username);
                std::cout << "密码: ";
                password = getPasswordFromConsole();
                
                if (authManager.authenticate(username, password)) {
                    break;
                } else {
                    std::cerr << "认证失败，请重试！" << std::endl;
                }
            } 
            else if (input == "2") {
                std::cout << "新用户名: ";
                std::getline(std::cin, username);
                std::cout << "密码: ";
                password = getPasswordFromConsole();
                
                authManager.registerUser(username, password);
                break;
            } 
            else {
                std::cerr << "无效输入！" << std::endl;
            }
        }
    }
    else{
        username = currentUser;
    }

    taskManager.loadTasks(username); //从taskManager加载用户任务数据
    xpSystem.saveToFile(username, territories);
    ReminderDaemon daemon(taskManager); //设置reminder
    daemon.start();

    std::cout << "\n\033[1;36m欢迎来到时间王国, " << username << "!\033[0m\n";
    std::cout << "输入 'help' 查看可用命令\n";

    std::string command;
    while (true) {
        std::cout << "\n\033[1;32m王国 > \033[0m";
        std::getline(std::cin, command);

        if (command == "exit" || command == "quit") break;
        if (command == "help") {
            std::cout << "可用命令:\n"
                << "  addtask - 添加新任务\n"
                << "  showtasks [day|month] [日期|月份] - 显示任务\n"
                << "  deltask <任务ID> - 删除任务\n"
                << "  kingdom - 显示王国状态\n"
                << "  help - 显示帮助\n"
                << "  exit - 退出程序\n";
        }
        else if (command.substr(0, 7) == "addtask") {
            if (command == "addtask") {// 交互式添加
                addTaskInteractive();
            }   
            else{
                std::istringstream iss(command);
                std::vector<std::string> args;
                std::string arg;
                while (iss >> arg) {
                    args.push_back(arg);
                }
                if (args.size() > 1) {
                    addTask(std::vector<std::string>(args.begin() + 1, args.end()));
                }
                else {
                    std::cerr << "错误: 需要任务参数" << std::endl;
                }
            }
        }
        else if (command.substr(0, 9) == "showtasks") {
            std::istringstream iss(command);
            std::vector<std::string> args;
            std::string arg;
            iss >> arg; // 跳过命令本身
            while (iss >> arg) {
                args.push_back(arg);
            }
            if (args.empty()){
                showTasks({ "day" });
            }
            else{
                showTasks(args);
            }
        }
        else if (command.substr(0, 7) == "deltask") {
            std::istringstream iss(command);
            std::vector<std::string> args;
            std::string arg;
            while (iss >> arg) {
                args.push_back(arg);
            }
            if (args.size() > 1) {
                deleteTask(std::vector<std::string>(args.begin() + 1, args.end()));
            }
            else {
                std::cerr << "错误: 需要任务ID" << std::endl;
            }
        }
        else if (command == "kingdom") {
            showKingdom(username);
        }
        else if (!command.empty()) {
            std::cerr << "未知命令: " << command << std::endl << "输入help来获得帮助" << std::endl;
        }
    }

    daemon.stop();
    taskManager.saveTasks(username);
    xpSystem.saveToFile(username, territories);
    std::cout << "王国数据已保存，再见!" << std::endl;
}

void CliHandler::showHelp() const {
    std::cout << "时间王国任务管理器 v1.0\n\n"
        << "用法: taskmaster <命令> [参数]\n\n"
        << "命令:\n"
        << "  register <用户名> <密码>  注册新用户\n"
        << "  run <用户名> <密码>       进入交互模式\n"
        << "  addtask <用户名> <密码> [参数] 添加任务\n"
        << "  showtasks <用户名> <密码> <范围> [日期|月份] 显示任务\n"
        << "  deltask <用户名> <密码> <任务ID> 删除任务\n"
        << "  kingdom <用户名> <密码>   显示王国状态\n"
        << "  help                      显示帮助\n"
        << "  version                   显示版本\n\n"
        << "任务参数格式:\n"
        << "  --name \"任务名称\"\n"
        << "  --start \"YYYY-MM-DD HH:MM\"\n"
        << "  --priority [low|medium|high]\n"
        << "  --category [study|entertainment|life|work]\n"
        << "  --remind \"YYYY-MM-DD HH:MM\" (可选)\n\n"
        << "示例:\n"
        << "  taskmaster register user1 pass123\n"
        << "  taskmaster run user1 pass123\n"
        << "  taskmaster addtask user1 pass123 --name \"项目会议\" --start \"2023-12-15 14:00\" --priority high --category work\n";
}

void CliHandler::showVersion() const {
    std::cout << "时间王国任务管理器 v1.0\n";
}

void CliHandler::registerUser(const std::string& username, const std::string& password) {
    authManager.registerUser(username, password);
}

void CliHandler::addTaskInteractive(){
    std::string name, startStr, priorityStr, categoryStr, remindStr;
    
    std::cout << "请输入任务名称: ";
    std::getline(std::cin, name);
    
    std::cout << "请输入开始时间(格式: YYYY-MM-DD HH:MM): ";
    std::getline(std::cin, startStr);
    
    std::cout << "请输入优先级(low/medium/high, 默认为medium): ";
    std::getline(std::cin, priorityStr);
    if (priorityStr.empty()) priorityStr = "medium";
    
    std::cout << "请输入分类(study/work/entertainment/life, 默认为life): ";
    std::getline(std::cin, categoryStr);
    if (categoryStr.empty()) categoryStr = "life";
    
    std::cout << "请输入提醒时间(格式: YYYY-MM-DD HH:MM, 可选): ";
    std::getline(std::cin, remindStr);
    
    // 构建参数向量并调用现有的addTask方法
    std::vector<std::string> args;
    args.push_back("--name");
    args.push_back(name);
    args.push_back("--start");
    args.push_back(startStr);
    args.push_back("--priority");
    args.push_back(priorityStr);
    args.push_back("--category");
    args.push_back(categoryStr);
    if (!remindStr.empty()) {
        args.push_back("--remind");
        args.push_back(remindStr);
    }
    addTask(args);
}

void CliHandler::addTask(const std::vector<std::string>& args) {
    std::string name, startStr, priorityStr = "medium", categoryStr = "life", remindStr;

    // 解析参数
    for (size_t i = 0; i < args.size(); i++) {
        if (args[i] == "--name" && i + 1 < args.size()) {
            name = args[++i];
        }
        else if (args[i] == "--start" && i + 1 < args.size()) {
            startStr = args[++i];
        }
        else if (args[i] == "--priority" && i + 1 < args.size()) {
            priorityStr = args[++i];
        }
        else if (args[i] == "--category" && i + 1 < args.size()) {
            categoryStr = args[++i];
        }
        else if (args[i] == "--remind" && i + 1 < args.size()) {
            remindStr = args[++i];
        }
    }

    // 验证必要参数
    if (name.empty() || startStr.empty()) {
        std::cerr << "错误: 需要任务名称和开始时间" << std::endl;
        return;
    }

    // 转换时间
    std::time_t startTime = Task::parseDateTime(startStr);
    std::time_t remindTime = remindStr.empty() ? 0 : Task::parseDateTime(remindStr);

    if (startTime == -1) {
        std::cerr << "错误: 无效的开始时间格式" << std::endl;
        return;
    }

    // 检查任务是否已存在
    if (taskManager.taskExists(name, startTime)) {
        std::cerr << "错误: 任务已存在（名称和开始时间相同）" << std::endl;
        return;
    }

    // 转换优先级
    Priority priority = Priority::MEDIUM;
    if (priorityStr == "low") priority = Priority::LOW;
    else if (priorityStr == "high") priority = Priority::HIGH;

    // 转换分类
    Category category = Category::LIFE;
    if (categoryStr == "study") category = Category::STUDY;
    else if (categoryStr == "entertainment") category = Category::ENTERTAINMENT;
    else if (categoryStr == "work") category = Category::WORK;

    // 创建并添加任务
    Task task(name, startTime, priority, category, remindTime);
    if (taskManager.addTask(task)) {
        // 游戏化: 添加XP
        int xp = 0;
        switch (priority) {
        case Priority::LOW: xp = 10; break;
        case Priority::MEDIUM: xp = 20; break;
        case Priority::HIGH: xp = 30; break;
        }
        xpSystem.addXP(xp);

        // 游戏化: 扩展领土
        TerritoryType territoryType = getTerritoryTypeForCategory(category);
        auto it = std::find_if(territories.begin(), territories.end(),
            [territoryType](const Territory& t) { return t.getType() == territoryType; });

        if (it != territories.end()) {
            it->expand();
        }
        else {
            territories.emplace_back(territoryType);
        }

        std::cout << "获得 " << xp << " XP! 当前XP: " << xpSystem.getCurrentXP() << std::endl;
    }
}

void CliHandler::showTasks(const std::vector<std::string>& args) {
    std::string scope = "day"; // 默认显示当天任务
    std::string dateStr;

    if (!args.empty()) {
        scope = args[0];
        if (args.size() > 1) {
            dateStr = args[1];
        }
    }

    std::time_t targetTime = std::time(nullptr);
    if (!dateStr.empty()) {
        targetTime = Task::parseDateTime(dateStr + " 00:00");
        if (targetTime == -1) {
            std::cerr << "无效的日期格式" << std::endl;
            return;
        }
    }

    if (scope == "day") {
        auto tasks = taskManager.getTasksForDay(targetTime);
        displayTasksForDay(tasks);
    }
    else if(scope == "month"){
        auto tasks = taskManager.getTasksForMonth(targetTime);
        displayTasksForMonth(tasks);
    }
    else{
        std::cerr << "错误：范围必须是 day 或 month\n " << std::endl;
    }
}

void CliHandler::deleteTask(const std::vector<std::string>& args) {
    if (args.empty()) {
        std::cerr << "需要任务ID" << std::endl;
        return;
    }

    try {
        int taskId = std::stoi(args[0]);
        Category category = taskManager.getTask(taskId).getCategory();
        if (taskManager.removeTask(taskId)) {
            // 游戏化: 删除任务扣除XP
            xpSystem.addXP(-15);
            std::cout << "扣除 15 XP! 当前XP: " << xpSystem.getCurrentXP() << std::endl;
            
            // 游戏化：缩减领土
            TerritoryType territoryType = getTerritoryTypeForCategory(category);
            auto it = std::find_if(territories.begin(), territories.end(),
                [territoryType](const Territory& t) { return t.getType() == territoryType; });

            if (it != territories.end()) {
                it->shrink();
            }
        }
    }
    catch (...) {
        std::cerr << "无效的任务ID" << std::endl;
    }
}

void CliHandler::showKingdom(const std::string& username) {
    displayKingdomStatus();
}

void CliHandler::displayTask(const Task& task) const {
    std::cout << "ID: " << task.getId() << " | "
        << "任务: " << task.getName() << " | "
        << "时间: " << task.getFormattedStartTime() << " | "
        << "优先级: " << task.getPriorityString() << " | "
        << "分类: " << task.getCategoryString() << std::endl;
}

void CliHandler::displayTasksForDay(const std::vector<Task>& tasks) const {
    if (tasks.empty()) {
        std::cout << "今天没有任务，享受你的时间吧！" << std::endl;
        return;
    }

    // 修复：将临时值存储到局部变量，再取地址
    time_t startTime = tasks[0].getStartTime();  // 存储到左值变量
    char timeBuffer[20];
    std::strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d", std::localtime(&startTime));  // 使用变量地址

    std::cout << "\n\033[1;35m===== " << timeBuffer << " 的任务 =====\033[0m\n";
    for (const auto& task : tasks) {
        displayTask(task);
    }
    std::cout << "\033[1;35m=============================\033[0m\n";
}

void CliHandler::displayTasksForMonth(const std::vector<Task>& tasks) const {
    if (tasks.empty()) {
        std::cout << "本月没有任务，享受你的时间吧！" << std::endl;
        return;
    }

    // 获取月份名称（如 "2023-11"）
    time_t firstTaskTime = tasks[0].getStartTime();
    char monthBuffer[20];
    std::strftime(monthBuffer, sizeof(monthBuffer), "%Y-%m", std::localtime(&firstTaskTime));

    std::cout << "\n\033[1;35m===== " << monthBuffer << " 月的任务 =====\033[0m\n";
    for (const auto& task : tasks) {
        displayTask(task); // 复用单个任务显示方法
    }
    std::cout << "\033[1;35m=============================\033[0m\n";
}

void CliHandler::displayKingdomStatus() const {
    std::cout << "\n\033[1;36m======= 你的时间王国 =======\033[0m\n";
    std::cout << "等级: " << xpSystem.getCurrentLevel() << " ★\n";
    std::cout << "经验值: " << xpSystem.getCurrentXP() << " XP\n";

    if (xpSystem.getCurrentLevel() < 10) {
        std::cout << "下一级需要: " << xpSystem.getXPToNextLevel() << " XP\n";
    }

    std::cout << "\n\033[1;33m领土:\033[0m\n";
    if (territories.empty()) {
        std::cout << "还没有领土，添加任务来扩展你的王国吧！\n";
    }
    else {
        for (const auto& territory : territories) {
            // 修复：用ASCII字符'#'替代多字节字符'■'，避免警告
            std::cout << " - " << territory.getName() << ": "
                      << std::string(territory.getSize(), '#')  // 替换为'#'
                      << " (" << territory.getSize() << ")\n";
        }
    }
    std::cout << "\033[1;36m=============================\033[0m\n";
}

TerritoryType CliHandler::getTerritoryTypeForCategory(Category category) const {
    switch (category) {
    case Category::STUDY: return TerritoryType::CASTLE;
    case Category::WORK: return TerritoryType::MOUNTAIN;
    case Category::ENTERTAINMENT: return TerritoryType::RIVER;
    case Category::LIFE: return TerritoryType::FOREST;
    default: return TerritoryType::PLAIN;
    }
}
